import cv2
import numpy as np
import socket
import struct
import time
import redis
import configparser

def main():
    config = configparser.ConfigParser()
    config.read('config.ini')

    server_host = config.get('server', 'host', fallback='localhost').strip("'").strip('"')
    server_port = config.getint('server', 'port', fallback=8080)
    redis_url = config.get('redis', 'url', fallback='redis://127.0.0.1/').strip("'").strip('"')
    plc_io_url = config.get('PLC', 'io_url', fallback='/sensor').strip("'").strip('"')
    plc_set_string = config.get('PLC', 'set_string', fallback='1').strip("'").strip('"')
    plc_reset_string = config.get('PLC', 'reset_string', fallback='0').strip("'").strip('"')
    camera_channel = config.getint('camera', 'channel', fallback=0)
    camera_interval = config.getint('camera', 'interval', fallback=5) / 1000

    print(f"server: {server_host}:{server_port}")

    r = redis.Redis.from_url(redis_url)
    last_value = r.get(plc_io_url)
    last_value = last_value.decode('utf-8') if last_value is not None else plc_reset_string
    iteration = 0

    server_url = f"{server_host}:{server_port}"
    stream = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    stream.connect((server_host, server_port))
    print("Server connected")

    cam = cv2.VideoCapture(camera_channel)
    cam.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

    while True:
        while True:
            value = r.get(plc_io_url)
            value = value.decode('utf-8') if value is not None else plc_reset_string
            if last_value != plc_set_string and value == plc_set_string:
                last_value = value
                print("IO change from reset to set, trigger sending images")
                break
            last_value = value
            cam.read()
            time.sleep(camera_interval)

        stream.send(struct.pack('>H', 3))
        iteration += 1
        print(f"Send images, iteration: {iteration}")

        for _ in range(3):
            ret, frame = cam.read()
            if not ret:
                continue

            _, buf = cv2.imencode(".jpg", frame)
            buf_size = len(buf)

            stream.send(struct.pack('>I', buf_size))
            stream.send(buf)

if __name__ == '__main__':
    main()
